Build Cartographer on ROS1 Noetic

Melodic에선 패키지로 잘 제공되는 Cartographer가 Noetic에선 바이너리 패키지로 제공되지 않는다. 귀찮게도 소스를 받아서 빌드해야 하는데, 다음과 같은 과정으로 설치하면 깔끔하게 처리 가능.

필요한 툴 설치

$ sudo apt-get install -y python3-wstool python3-rosdep ninja-build stow

워크스페이스에 디렉토리를 만들고 필요한 소스를 받아온다.

$ cd ~/catkin_ws/src
$ mkdir cartographer
$ cd cartographer
$ git clone https://github.com/cartographer-project/cartographer.git
$ git clone https://github.com/cartographer-project/cartographer_ros.git

빌드에 필요한 패키지를 자동으로 설치한다.

$ pwd
/home/<user-name>/catkin_ws/src/cartgrapher
$ rosdep install --from-paths . --ignore-src -r -y

libabseil 설치.

$ cd catrographer/scripts
$ ./install_abseil.sh

이제 빌드하면 에러없이 정상적으로 빌드 가능.

$ catkin build

끝.!

socat 사용 예시

socat은 리눅스에서 사용할 수 있는 다목적 릴레이 프로그램이다. 쉽게 얘기해서 Source, Sink 간에 두 개의 단방향 채널을 열어, 서로 연결해준다.

설치는 간단히 apt를 이용하여 설치가 가능하다.

$ sudo apt install socat

사용방법은

$ socat [option] <source> <sink>

와 같이 사용하며, 옵션은 socket -h 를 이용해 확인 가능. 많이 사용하는 것으로는 -d 옵셩는 로그 메시지 출력, -u, -U를 이용해 단방향, 역방향 설정 등이 있다.

source 및 sink에는 linux에서 사용하는 거의 모든 인터페이스들이 적용 가능하다.

  • Files
  • Pipes
  • Devices (serial line, pseudo-terminal, etc)
  • `Sockets (UNIX, IP4, IP6 – raw, UDP, TCP)
  • SSL sockets
  • Proxy CONNECT connections
  • File descriptors (stdin, etc)
  • The GNU line editor (readline)
  • Programs
  • Combinations of two of these

실제 사용 예를 들어본다면,

  • STDIN <-> STDOUT: 키보드 입력, 화면 출력
$ socat -dd STDIN STDOUT
  • TCP 2000포트로 연결하면 자동으로 TCP 22 포트로 연결
$ socat -dd TCP-LISTEN:2000,reuseaddr,fork TCP:0.0.0.0:22
  • TCP 8080포트로 연결하면 자동으로 data.txt 파일을 생성하고 수신받은 내용 저장
$ socat -dd -u TCP-LISTEN:8080,reuseaddr,fork open:data.txt,create,append

이외에도 시리얼포트 등도 가능하여. 간단히 시리얼포트-이더넷 기능 구현 가능하고, .UDP를 TCP로 변환, 그 반대 역시 가능하여, 활용 방법은 무궁무진한다.

하나의 디스크에 여러가지 버전의 Ubuntu 설치하기

ROS를 사용하여 개발을 하다보니, ROS의 버전에 따라 Ubuntu의 배포판이 달라져야 하는 경우가 생긴다. 예를 들자면, ROS2의 현재 최신 LTS버전은 Humble로 Ubuntu 22.04에서 설치가 되어야 하고, ROS1의 최종 LTS버전은 Noetic으로 Ubuntu 20.04에서 지원이 멈춰있다 (이제 더이상 배포판 업데이트 지원 불가).

따라서 이 두가지 경우를 모두 사용하기 위해선, 각각 따로 개발용 PC를 구비하던가 아니면 외장 SSD를 이용하는 방법이 있긴 하지만, 번거로운건 어쩔수 없다.

하나의 SSD에 GRUB 부트로더를 하나만 사용하고, 스왑 파티션도 공용으로 사용하고, 루트 파티션만 분리하여 설치하면 위와 같은 문제가 깔끔이 해결된다. 여전히 재부팅이 필요한 건 어쩔수 없지만..^^

기록 차원에서 설치 순서를 간단히 정리해본다. 윈도우와 듀얼부팅으로 사용할 때도 적용 가능. 물론 배포판의 버전이 달라도 상관없음.

먼저, 가장 최신 버전의 배포판을 설치한다. 이건 여느때와 마찬가지로 그냥 설치하면 됨.

설치할 때, 디스크의 파티션을 설정하는 부분이 있는데, 이때 다음과 같은 구조로 만들어준다.

/dev/sda1    /boot    EFI     2000MB
/dev/sda2    /        ext4    200000MB
/dev/sda3    None     ext4    200000MB
/dev/sda4    swap     swap    32768MB

앞쪽 디스크 이름은 각자의 개발 환경에 따라 다를테니, 유념하시면 되고, 기존과 다른 점은 /boot 파티션을 따로 분리한 것과 루트 (/) 파티션을 만들고 또 동일한 크기 혹은 원하는 크기로 또 하나의 파티션을 만들어 놓은 것이다.

이제 설치를 완료 (루트 파티션을 /dev/sda2로 선택)하고.. 부팅이 제대로 되는 것을 확인한 다음…

다음으로 추가로 설치할 배포판 설치를 진행한다. 이때는 바로 설치를 진행하지 말고, Try Ubuntu 등 일단 임시로 사용할 수 있는 모드로 진입.

여기에선 부트로더 설치를 하지 않고, 배포판 설치를 진행하야 하므로, 터미널을 열고

$ ubiquity -b

와 같이 실행하여 설치를 진행한다. 디스크 설정 시, 설치할 파티션을 위에서 만든 /dev/sda3로 선택한다. 설치가 완료되면, 그냥 재부팅.

재부팅하면, 기존에 설치한 최신 배포판으로 부팅이 될텐데, 완료되면 터미널을 열고,

$ sudo update-grub2

를 하면, 자동으로 방금 전에 설치한 추가 배포판의 커널을 인식하여 GRUB의 부트 엔트리에 등록해준다. 또 기본값으로는 GRUB가 후다닥 지나가버리게 설정되어 있으므로, /etc/default/grub 파일을 열어서 다음과 같이 수정해준다.

# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
#   info -f grub -n 'Simple configuration'

GRUB_DEFAULT=0
GRUB_TIMEOUT_STYLE=menu
GRUB_TIMEOUT=10
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX=""

이제 끝!

Ubuntu에서 DDM 기능 대체하기

Dell 모니터 중 KVM 기능을 지원하는 제품의 경우, Windows나 macOS에서는 DDM (Dell Display Manager)라는 프로그램을 통해서 모니터를 키보드를 통해 제어할 수 있다.

이를 이용하면 유용한 점이, 모니터를 직접 조작하지 않고도, 입력 소스를 선택할 수 있어 두 대의 PC를 오가며 쉽게 작업할 수 있다는 점이다.

다만 아쉽게도 아직까지 Ubuntu에서 동작하는 DDM은 없는 상황이다. 하지만 구글링을 해보면 쉽게 이를 대체할 수 있는 방법이 나온다.

기본적으로 DDM의 역할은 모니터에 연결된 특정칩에 명령을 전달하는 것인데, 이 명령이 DDC/CI 기능을 이용한다. 아마 게임기나 셋탑박스를 연결할 때, 케이블을 꼽기만 해도 해당 입력소스로 자동으로 전환되는 것을 경험해보셨다면, 그 모니터가 DDC/CI 기능을 지원한다는 의미이다.

Ubuntu에도 이러한 기능을 수행하는 커맨드가 존재하는데, ddccontrol 이 그것이다.

설치는 다음과 같이

$ sudo apt install ddccontrol

설치하면 되고..

이제 실행을 해보면, 먼저 모니터를 인식하는지를 확인해보면…

$ ddccontrol -p
ddccontrol version 0.6.0
Copyright 2004-2005 Oleg I. Vdovikin (oleg@cs.msu.su)
Copyright 2004-2006 Nicolas Boichat (nicolas@boichat.ch)
This program comes with ABSOLUTELY NO WARRANTY.
You may redistribute copies of this program under the terms of the GNU General Public License.

Detected monitors :
 - Device: dev:/dev/i2c-6
   DDC/CI supported: Yes
   Monitor Name: VESA standard monitor
   Input type: Digital
  (Automatically selected)
Reading EDID and initializing DDC/CI at bus dev:/dev/i2c-6...
I/O warning : failed to load external entity "/usr/share/ddccontrol-db/monitor/DEL426A.xml"
Document not parsed successfully.
I/O warning : failed to load external entity "/usr/share/ddccontrol-db/monitor/DELlcd.xml"
Document not parsed successfully.

EDID readings:
	Plug and Play ID: DEL426A [VESA standard monitor]
	Input type: Analog

...
= VESA standard monitor
...
> Input settings
	> Input sources
		> id=inputsource, name=Input Source Select (Main), address=0x60, delay=-1ms, type=2
		  Possible values:
			> id=analog - name=Analog, value=1
			> id=digital - name=Digital, value=3
		  supported, value=3855, maximum=14
...

와 같이 연결된 모니터 정보가 인식된다.

이중, 중요한 것이, 연결되어 있는 디바이스 정보인데, 여기에선 /dev/i2c-6으로 되어 있다. 또, Input sources를 설정하는 레지스터 주소가 0x60으로 되어 있는 것을 알 수 있다.

이제 0x60에 특정한 값을 넣으면, 해당되는 입력 소스로 전환할 수 있다는 것인데… 이 특정한 값이 무엇인지를 파악해야 하는데, 역시 검색해보면 답이 바로 나온다.

  • Display Port : 0x0f (15)
  • USB-C : 0x1B (27)
  • HDMI : 0x11 (17)

이다.

즉 터미널에서 다음과 같이 입력하면, USB-C 입력소스로 즉시 전환된다.

$ ddccontrol -r 0x60 -w 27 dev:/dev/i2c-6

이제, 이 명령을 키보드 단축키로 지정하면 쉽게 사용 가능.

설정에서 키보드 > 키보드 단축키 설정 > 사용자 단축키 설정

이제, 위 단축키를 이용하면, 모니터의 입력소스를 조정하여 쉽게 전환이 가능하다.